//
//  LBSharpenFilter.mm
//  OpenGLGame
//
//  Created by Nguyen Cong Huy on 11/27/12.
//  Copyright (c) 2012 UIT. All rights reserved.
//

#include <iostream>
#include "LBSharpenFilter.h"
#include "LBGraphics.h"

char sharpenFilterVerShader[]=""
"attribute vec4 position;"
"attribute vec4 texCoor;"

"uniform mat4 mWorld;"
"uniform mat4 mProjection;"

"uniform float imageWidthFactor; "
"uniform float imageHeightFactor; "
"uniform float sharpness;"

"varying vec2 vtexCoor;"
"varying vec2 leftTextureCoordinate;"
"varying vec2 rightTextureCoordinate; "
"varying vec2 topTextureCoordinate;"
"varying vec2 bottomTextureCoordinate;"

"varying float centerMultiplier;"
"varying float edgeMultiplier;"

"void main()"
"{"
"    gl_Position = mProjection * mWorld * position;"
    
"    mediump vec2 widthStep = vec2(imageWidthFactor, 0.0);"
"    mediump vec2 heightStep = vec2(0.0, imageHeightFactor);"
    
"    vtexCoor = texCoor.xy;"
"    leftTextureCoordinate = texCoor.xy - widthStep;"
"    rightTextureCoordinate = texCoor.xy + widthStep;"
"    topTextureCoordinate = texCoor.xy + heightStep;     "
"    bottomTextureCoordinate = texCoor.xy - heightStep;"
    
"    centerMultiplier = 1.0 + 4.0 * sharpness;"
"    edgeMultiplier = sharpness;"
"}";

char sharpenFilterFragShader[]=""
"precision highp float;"

"varying highp vec2 vtexCoor;"
"varying highp vec2 leftTextureCoordinate;"
"varying highp vec2 rightTextureCoordinate; "
"varying highp vec2 topTextureCoordinate;"
"varying highp vec2 bottomTextureCoordinate;"

"varying highp float centerMultiplier;"
"varying highp float edgeMultiplier;"

"uniform sampler2D texture;"

"void main()"
"{"
"    mediump vec3 textureColor = texture2D(texture, vtexCoor).rgb;"
"    mediump vec3 leftTextureColor = texture2D(texture, leftTextureCoordinate).rgb;"
"    mediump vec3 rightTextureColor = texture2D(texture, rightTextureCoordinate).rgb;"
"    mediump vec3 topTextureColor = texture2D(texture, topTextureCoordinate).rgb;"
"    mediump vec3 bottomTextureColor = texture2D(texture, bottomTextureCoordinate).rgb;"
    
"    gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(texture, bottomTextureCoordinate).w);"
"}";

LBSharpenFilter::LBSharpenFilter(){
    init(sharpenFilterVerShader, sharpenFilterFragShader);
    
    sharpnessUniform = program->uniformIndex("sharpness");
    imageWidthFactorUniform = program->uniformIndex("imageWidthFactor");
    imageHeightFactorUniform = program->uniformIndex("imageHeightFactor");
    setSharpness(2.0);
    setupFilterForSize(320, 480);
}

void LBSharpenFilter::setSharpness(float sharpness){
    this->sharpness = sharpness;
    LBGraphics::getInstance()->useProgram(program);
    glUniform1f(sharpnessUniform, sharpness);
}

void LBSharpenFilter::setupFilterForSize(int width, int height){
    LBGraphics::getInstance()->useProgram(program);
    glUniform1f(imageWidthFactorUniform, 1.0f/width);
    glUniform1f(imageHeightFactorUniform, 1.0f/height);
}